package accessstruct;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
import it.unisa.dia.gas.jpbc.Field;


/**
 * 读取参数工具类
 */
public class Tool {
    /**
     * 将配置信息写入文件
     * @param prop
     * @param fileName
     */
    public static void storePropToFile(Properties prop, String fileName){
        try(FileOutputStream out = new FileOutputStream(fileName)){
            prop.store(out, null);
        }
        catch (IOException e) {
            e.printStackTrace();
            System.out.println(fileName + " save failed!");
            System.exit(-1);
        }
    }

    /**
     * 附加到配置信息文件件中
     * @param prop
     * @param fileName
     */
    public static void appendStorePropToFile(Properties prop, String fileName){
        try(FileOutputStream out = new FileOutputStream(fileName,true)){
            prop.store(out, null);
        }
        catch (IOException e) {
            e.printStackTrace();
            System.out.println(fileName + " save failed!");
            System.exit(-1);
        }
    }


    /**
     * 从文件读取出配置信息
     * @param fileName
     * @return
     */
    public static Properties loadPropFromFile(String fileName) {
        Properties prop = new Properties();
        try (FileInputStream in = new FileInputStream(fileName)){
            prop.load(in);
        }
        catch (IOException e){
            e.printStackTrace();
            System.out.println(fileName + " load failed!");
            System.exit(-1);
        }
        return prop;
    }

    /**
     * sha1算法，hash运算
     * @param content
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static byte[] sha1(String content) throws NoSuchAlgorithmException {
        MessageDigest instance = MessageDigest.getInstance("SHA-256");
        instance.update(content.getBytes());
        return instance.digest();
    }
    /**
     * hash函数由H‘ = Gt---> Zq
     * @param element
     * @return
     */
    public static Element GthashToZp(Pairing pairing, Element element) {
        // Get the order of the Zp group
        BigInteger zpOrder = pairing.getZr().getOrder();

        // Compute the hash of the element
        byte[] elementBytes = element.toBytes();
        BigInteger hashValue = new BigInteger(1, elementBytes);

        // Reduce the hash value modulo the order of the Zp group
        hashValue = hashValue.mod(zpOrder);

        // Create a new Element from the hash value
        return pairing.getZr().newElement(hashValue);
    }

    /**
     * hash函数H {0，1}*---->Gt
     * @param binaryString
     * @return
     */
    public static Element BinToGt(String binaryString){
        try {
//            String binaryString = Integer.toBinaryString(att);
            // 创建一个SHA-256哈希对象
            MessageDigest digest = MessageDigest.getInstance("SHA-256");

            // 计算二进制字符串的哈希值
            byte[] hashBytes = digest.digest(binaryString.getBytes());

            // 从哈希值创建一个Gt群元素
            Pairing pairing = PairingFactory.getPairing("a.properties"); // 使用合适的参数文件
            Field<?> gtField = pairing.getGT();
            Element GtElement = gtField.newElementFromHash(hashBytes, 0, hashBytes.length);
            return GtElement;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * String 到  BinaryString
     * @param str
     * @return
     */
    public static String stringToBinaryString(String str) {
        // 将字符串转换为字节数组
        byte[] bytes = str.getBytes();

        // 使用BigInteger将字节数组转换为大整数
        BigInteger bigInteger = new BigInteger(1, bytes);

        // 使用toString方法将大整数表示为二进制字符串
        String binaryString = bigInteger.toString(2);

        // 返回结果
        return binaryString;
    }

    /**
     * 将属性集合转化成策略，这里只测试与策略，or同样可行，但是需要自行编写
     * @param array
     * @return
     */
    public static String convertToAcP(String[] array) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            sb.append(array[i]);
            if (i < array.length - 1) {
                sb.append(" and ");
            }
        }

        return sb.toString();
    }




}


